home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 32 / Amiga Format AFCD32 (Nov 1998, Issue 117).iso / -seriously_amiga- / programming / other / cgraphx / c / examples / window.c < prev   
C/C++ Source or Header  |  1998-08-10  |  10KB  |  403 lines

  1.  
  2. #include <exec/memory.h>
  3. #include <intuition/intuitionbase.h>
  4. #include <cybergraphx/cybergraphics.h>  /* v41 uses cybergraphx/ dir */
  5.  
  6. #ifdef __SASC_60
  7. #include <proto/cybergraphics.h>
  8. #include <proto/dos.h>
  9. #include <proto/exec.h>
  10. #include <proto/intuition.h>
  11. #else
  12. #include <clib/cybergraphics_protos.h>
  13. #include <clib/dos_protos.h>
  14. #include <clib/exec_protos.h>
  15. #include <clib/intuition_protos.h>
  16. #ifndef _DCC
  17. #include <inline/cybergraphics.h>
  18. #endif
  19. #endif
  20.  
  21. #include <stdlib.h>
  22.  
  23. #define CYBERGFXVERSION  41L
  24.  
  25. #define SCREEN_WANTED_WIDTH  640L
  26. #define SCREEN_WANTED_HEIGHT 480L
  27. #define SCREEN_WANTED_DEPTH   24L
  28. #define SCREEN_MIN_DEPTH      15L
  29.  
  30. #define IMAGE_WIDTH  256L
  31. #define IMAGE_HEIGHT 256L
  32. #define IMAGE_BPP    3L
  33.  
  34. #ifdef __SASC_60
  35. #include <string.h>
  36. #define MIN(a,b) __builtin_min(a,b)
  37. #else
  38. #define MIN(a,b) ((a)<(b)?(a):(b))
  39. #endif
  40. #define SIGMASK(w) (1L<<((w)->UserPort->mp_SigBit))
  41. #define GETIMSG(w) ((struct IntuiMessage *)GetMsg((w)->UserPort))
  42.  
  43. #ifdef __SASC_650
  44. /* use SAS/C 6.5x's autoinit feature */
  45.  
  46. LONG __oslibversion   = 39L;
  47. LONG __CGFXlibversion = CYBERGFXVERSION;
  48. #else
  49. struct IntuitionBase *IntuitionBase;
  50. struct Library *CyberGfxBase;
  51. #endif
  52.  
  53. #ifdef __SASC_650
  54. char Version[] = "$VER: Window 0.4 " __AMIGADATE__ ;
  55. #else
  56. #ifdef _DCC
  57. char Version[] = "$VER: Window 0.4 (" __COMMODORE_DATE__  ")";
  58. #else
  59. char Version[] = "$VER: Window 0.4 (" __DATE__  ")";
  60. #endif
  61. #endif
  62.  
  63. /*
  64.  
  65.         display error message
  66.  
  67. */
  68.  
  69. void ErrorF(char *Format,...)
  70.  
  71. {
  72.  void *Data;
  73.  
  74.  Data=&Format+1L;
  75.  if (((struct Process *)FindTask(NULL))->pr_CLI)
  76.   {
  77.    (void)VPrintf(Format,Data);
  78.    (void)FPutC(Output(),'\n');
  79.    (void)Flush(Output());
  80.   }
  81.  else
  82.   {
  83.    struct EasyStruct EasyStruct;
  84.    ULONG IDCMPFlags;
  85.  
  86.    EasyStruct.es_StructSize=sizeof(struct EasyStruct);
  87.    EasyStruct.es_Flags=0L;
  88.    EasyStruct.es_Title="Error";
  89.    EasyStruct.es_TextFormat=Format;
  90.    EasyStruct.es_GadgetFormat="Ok";
  91.  
  92.    IDCMPFlags=0L;
  93.    (void)EasyRequestArgs(NULL,&EasyStruct,&IDCMPFlags,Data);
  94.   }
  95. }
  96.  
  97. /*
  98.  
  99.         create image data
  100.  
  101. */
  102.  
  103. void CreateImageData(UBYTE *Image,ULONG Width,ULONG Height)
  104.  
  105. {
  106.  ULONG X,Y;
  107.  
  108.  for (Y=0; Y<Height; Y++)
  109.   for (X=0; X<Width; X++)
  110.    {
  111.     *Image++=(UBYTE)X; /* Red   */
  112.     *Image++=(UBYTE)Y; /* Green */
  113.     *Image++=0;        /* Blue  */
  114.    }
  115. }
  116.  
  117. /*
  118.  
  119.         window handling
  120.  
  121. */
  122.  
  123. LONG InnerWidth(struct Window *Window)
  124.  
  125. {
  126.  return Window->Width-Window->BorderLeft-Window->BorderRight;
  127. }
  128.  
  129. LONG InnerHeight(struct Window *Window)
  130.  
  131. {
  132.  return Window->Height-Window->BorderTop-Window->BorderBottom;
  133. }
  134.  
  135. void RedrawScaleWindow(struct Window *ScaleWindow,UBYTE *ImageData)
  136.  
  137. {
  138.  (void)ScalePixelArray(ImageData,IMAGE_WIDTH,IMAGE_HEIGHT,
  139.                        IMAGE_WIDTH*IMAGE_BPP,
  140.                        ScaleWindow->RPort,
  141.                        ScaleWindow->BorderLeft,ScaleWindow->BorderTop,
  142.                        InnerWidth(ScaleWindow),
  143.                        InnerHeight(ScaleWindow),
  144.                        RECTFMT_RGB);
  145. }
  146.  
  147. void RedrawWriteWindow(struct Window *WriteWindow,UBYTE *ImageData)
  148.  
  149. {
  150.  (void)WritePixelArray(ImageData,0,0,
  151.                        IMAGE_WIDTH*IMAGE_BPP,
  152.                        WriteWindow->RPort,
  153.                        WriteWindow->BorderLeft,WriteWindow->BorderTop,
  154.                        InnerWidth(WriteWindow),
  155.                        InnerHeight(WriteWindow),
  156.                        RECTFMT_RGB);
  157. }
  158.  
  159. /*
  160.  
  161.         screen depth fallback
  162.  
  163. */
  164.  
  165. ULONG NextDepth(ULONG Depth)
  166.  
  167. {
  168.  switch (Depth)
  169.   {
  170.    case 24L: /* 24Bit not available? Try 16Bit!      */
  171.     return 16L;
  172.    case 16L: /* 15Bit not available? Try 15Bit!      */
  173.     return 15L;
  174.    default:  /* Not even 15Bit available? Forget it! */
  175.     return 0L;
  176.   }
  177. }
  178.  
  179. /*
  180.  
  181.         main program
  182.  
  183. */
  184.  
  185. int main(int argc, char **argv)
  186.  
  187. {
  188.  ULONG DisplayID,Depth;
  189.  struct Screen *CyberScreen;
  190.  struct Window *ScaleWindow,*WriteWindow;
  191.  UBYTE *ImageData;
  192.  LONG Done;
  193.  struct IntuiMessage *IntMsg;
  194.  
  195. #ifndef __SASC_650
  196.  if ((IntuitionBase=(struct IntuitionBase *)
  197.                     OpenLibrary("intuition.library",39L))==NULL) return 20;
  198.  
  199.  if ((CyberGfxBase=OpenLibrary(CYBERGFXNAME,CYBERGFXVERSION))==NULL)
  200.   {
  201.    CloseLibrary (&IntuitionBase->LibNode);
  202.  
  203.    ErrorF ("Can't open \"%s\" version %ld or newer.",
  204.            CYBERGFXNAME,CYBERGFXVERSION);
  205.    return 10;
  206.   }
  207. #endif
  208.  
  209. /* Let CyberGraphX search a display mode for us! */
  210.  
  211.  Depth=SCREEN_WANTED_DEPTH;
  212.  while (Depth)
  213.   {
  214.    if ((DisplayID=BestCModeIDTags(CYBRBIDTG_NominalWidth,SCREEN_WANTED_WIDTH,
  215.                                   CYBRBIDTG_NominalHeight,SCREEN_WANTED_HEIGHT,
  216.                                   CYBRBIDTG_Depth,Depth,
  217.                                   TAG_DONE))!=INVALID_ID)
  218.     {
  219. /* Because older version of the "cybergraphics.library" don't handle */
  220. /* CYBRBIDTG_Depth properly we query the real depth of the mode.     */
  221.  
  222.      Depth=GetCyberIDAttr(CYBRIDATTR_DEPTH,DisplayID);
  223.      break;
  224.     }
  225. /* retry with less bits per pixel */
  226.    Depth=NextDepth(Depth);
  227.   }
  228.  
  229.  if (Depth<SCREEN_MIN_DEPTH)
  230.   {
  231. #ifndef __SASC_650
  232.    CloseLibrary (CyberGfxBase);
  233.    CloseLibrary (&IntuitionBase->LibNode);
  234. #endif
  235.  
  236.    ErrorF ("Can't find suitable display mode for %ldx%ldx%ld.",
  237.            SCREEN_WANTED_WIDTH,SCREEN_WANTED_HEIGHT,SCREEN_WANTED_DEPTH);
  238.    return 5;
  239.   }
  240.  
  241. /* open screen, but let Intuition choose the actual dimensions */
  242.  
  243.  if ((CyberScreen=OpenScreenTags(NULL,
  244.                                  SA_Title,"CyberGraphX Demo",
  245.                                  SA_DisplayID,DisplayID,
  246.                                  SA_Depth,Depth,
  247.                                  TAG_DONE))==NULL)
  248.   {
  249. #ifndef __SASC_650
  250.    CloseLibrary (CyberGfxBase);
  251.    CloseLibrary (&IntuitionBase->LibNode);
  252. #endif
  253.  
  254.    ErrorF ("Can't open screen.");
  255.    return 5;
  256.   }
  257.  
  258. /* create Scale window */
  259.  
  260.  if ((ScaleWindow=OpenWindowTags(NULL,
  261.                                  WA_Title,"Scale",
  262.                                  WA_Flags,WFLG_ACTIVATE|WFLG_SIMPLE_REFRESH|
  263.                                   WFLG_SIZEGADGET|WFLG_RMBTRAP|WFLG_DRAGBAR|
  264.                                   WFLG_DEPTHGADGET|WFLG_CLOSEGADGET,
  265.                                  WA_IDCMP,
  266.                                   IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|
  267.                                   IDCMP_SIZEVERIFY|IDCMP_NEWSIZE,
  268.                                  WA_Left,16,
  269.                                  WA_Top,CyberScreen->BarHeight+16,
  270.                                  WA_Width,IMAGE_WIDTH,
  271.                                  WA_Height,IMAGE_HEIGHT,
  272.                                  WA_CustomScreen,CyberScreen,
  273.                                  TAG_DONE))==NULL)
  274.   {
  275.    CloseScreen (CyberScreen);
  276. #ifndef __SASC_650
  277.    CloseLibrary (CyberGfxBase);
  278.    CloseLibrary (&IntuitionBase->LibNode);
  279. #endif
  280.  
  281.    ErrorF ("Can't open scale window.");
  282.    return 5;
  283.   }
  284.  (void)WindowLimits(ScaleWindow,
  285.                     ScaleWindow->BorderLeft+ScaleWindow->BorderRight+1,
  286.                     ScaleWindow->BorderTop+ScaleWindow->BorderBottom+1,
  287.                     CyberScreen->Width,CyberScreen->Height);
  288.  
  289. /* create Write window */
  290.  
  291.  if ((WriteWindow=OpenWindowTags(NULL,
  292.                                  WA_Title,"Write",
  293.                                  WA_Flags,WFLG_SIMPLE_REFRESH|
  294.                                   WFLG_SIZEGADGET|WFLG_RMBTRAP|WFLG_DRAGBAR|
  295.                                   WFLG_DEPTHGADGET|WFLG_CLOSEGADGET,
  296.                                  WA_IDCMP,
  297.                                   IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|
  298.                                   IDCMP_SIZEVERIFY|IDCMP_NEWSIZE,
  299.                                  WA_Left,CyberScreen->Width-16-IMAGE_WIDTH,
  300.                                  WA_Top,CyberScreen->BarHeight+16,
  301.                                  WA_Width,IMAGE_WIDTH,
  302.                                  WA_Height,IMAGE_HEIGHT,
  303.                                  WA_CustomScreen,CyberScreen,
  304.                                  TAG_DONE))==NULL)
  305.   {
  306.    CloseWindow (ScaleWindow);
  307.    CloseScreen (CyberScreen);
  308. #ifndef __SASC_650
  309.    CloseLibrary (CyberGfxBase);
  310.    CloseLibrary (&IntuitionBase->LibNode);
  311. #endif
  312.  
  313.    ErrorF ("Can't open write window.");
  314.    return 5;
  315.   }
  316.  (void)WindowLimits(WriteWindow,
  317.                     WriteWindow->BorderLeft+WriteWindow->BorderRight+1,
  318.                     WriteWindow->BorderTop+WriteWindow->BorderBottom+1,
  319.                     MIN(CyberScreen->Width,WriteWindow->BorderLeft+
  320.                         WriteWindow->BorderRight+IMAGE_WIDTH),
  321.                     MIN(CyberScreen->Height,WriteWindow->BorderTop+
  322.                         WriteWindow->BorderBottom+IMAGE_HEIGHT));
  323.  
  324. /* allocate and create image data */
  325.  
  326.  if ((ImageData=AllocVec(IMAGE_WIDTH*IMAGE_HEIGHT*IMAGE_BPP,MEMF_PUBLIC))==NULL)
  327.   {
  328.    CloseWindow (WriteWindow);
  329.    CloseWindow (ScaleWindow);
  330.    CloseScreen (CyberScreen);
  331. #ifndef __SASC_650
  332.    CloseLibrary (CyberGfxBase);
  333.    CloseLibrary (&IntuitionBase->LibNode);
  334. #endif
  335.  
  336.    ErrorF ("Out of memory.");
  337.    return 5;
  338.   }
  339.  CreateImageData (ImageData,IMAGE_WIDTH,IMAGE_HEIGHT);
  340.  
  341. /* event loop */
  342.  
  343.  RedrawScaleWindow (ScaleWindow,ImageData);
  344.  RedrawWriteWindow (WriteWindow,ImageData);
  345.  
  346.  Done=FALSE;
  347.  while (!Done)
  348.   {
  349.    (void)Wait(SIGMASK(WriteWindow)|SIGMASK(ScaleWindow));
  350.  
  351.    while (IntMsg=GETIMSG(ScaleWindow))
  352.     {
  353.      switch (IntMsg->Class)
  354.       {
  355.        case IDCMP_REFRESHWINDOW:
  356.         BeginRefresh (ScaleWindow);
  357.         RedrawScaleWindow (ScaleWindow,ImageData);
  358.         EndRefresh (ScaleWindow,TRUE);
  359.         break;
  360.        case IDCMP_NEWSIZE:
  361.         RedrawScaleWindow (ScaleWindow,ImageData);
  362.         break;
  363.        case IDCMP_CLOSEWINDOW:
  364.         Done=TRUE;
  365.       }
  366.  
  367.      ReplyMsg (&IntMsg->ExecMessage);
  368.     }
  369.  
  370.    while (IntMsg=GETIMSG(WriteWindow))
  371.     {
  372.      switch (IntMsg->Class)
  373.       {
  374.        case IDCMP_REFRESHWINDOW:
  375.         BeginRefresh (WriteWindow);
  376.         RedrawWriteWindow (WriteWindow,ImageData);
  377.         EndRefresh (WriteWindow,TRUE);
  378.         break;
  379.        case IDCMP_NEWSIZE:
  380.         RedrawWriteWindow (WriteWindow,ImageData);
  381.         break;
  382.        case IDCMP_CLOSEWINDOW:
  383.         Done=TRUE;
  384.       }
  385.  
  386.      ReplyMsg (&IntMsg->ExecMessage);
  387.     }
  388.   }
  389.  
  390. /* cleanup */
  391.  
  392.  FreeVec (ImageData);
  393.  CloseWindow (WriteWindow);
  394.  CloseWindow (ScaleWindow);
  395.  CloseScreen (CyberScreen);
  396. #ifndef __SASC_650
  397.  CloseLibrary (CyberGfxBase);
  398.  CloseLibrary (&IntuitionBase->LibNode);
  399. #endif
  400.  
  401.  return 0;
  402. }
  403.